package com.studerb.tasks;

import java.io.BufferedReader;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;

import org.apache.commons.net.io.DotTerminatedMessageReader;
import org.apache.commons.net.nntp.NNTPCommand;
import org.apache.commons.net.nntp.NNTPReply;
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.GenericApplicationContext;

import com.studerb.exceptions.ServiceException;
import com.studerb.model.Server;
import com.studerb.nntp.NntpConnection;
import com.studerb.service.ServerService;
import com.studerb.util.Constants;

public class ListCommandProducerTask implements Callable<Void>, ApplicationContextAware {

    private final static Logger log = Logger.getLogger(ListCommandProducerTask.class);
    private final static int LOG_COUNT = 10000;
    private GenericApplicationContext appContext;
    private NntpConnection conn;
    private BlockingQueue<String> queue;
    private Server master;
    private BufferedReader reader;
    @Autowired private ServerService serverService;

    public ListCommandProducerTask() {
    }

    public Void call() throws Exception {
        log.debug("group producer starting");
        try{
            master = serverService.getMasterServer();
            log.info("updating all groups from server: " + master.toString());
            NntpConnection conn = (NntpConnection)appContext.getBean("nntpConnection");
            conn.setServer(master);
            conn.connect();
            int reply = conn.sendCommand(NNTPCommand.LIST);
            if(( !NNTPReply.isPositiveCompletion(reply)) || (reply != NNTPReply.LIST_OF_NEWSGROUP_FOLLOWS))
                throw new ServiceException("Error listing groups: reply: " + conn.getReply());
            reader = new BufferedReader(new DotTerminatedMessageReader(conn.getReader()));
            String temp;
            int count = 0;
            while((temp = reader.readLine()) != null){
                queue.put(temp);
                ++count;
                if(count % LOG_COUNT == 0)
                    log.debug(count + ": " + temp);
            }
            log.debug("Finished downloading " + count + " groups");
            return null;
        }
        finally{
            queue.put(Constants.END_OF_QUEUE);
            conn.disconnect();
        }
    }

    @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.appContext = (GenericApplicationContext)applicationContext;
    }

    public void setQueue(BlockingQueue<String> queue) {
        this.queue = queue;
    }
}